/*
 * Copyright 2002-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.support;

import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.core.AliasRegistry;
/**
 * Interface for registries that hold bean definitions, for example RootBeanDefinition
 * and ChildBeanDefinition instances. Typically implemented by BeanFactories that
 * internally work with the AbstractBeanDefinition hierarchy.
 *
 * 用于保存 BeanDefinition 的注册表接口，例如 RootBeanDefinition 和 ChildBeanDefinition。
 * 通常由基于 AbstractBeanDefinition 层次结构工作的 BeanFactory 实现。
 * ——核心功能是：提供对 BeanDefinition 的统一管理入口（增、删、查、改），
 *   这是 Spring IOC 容器的“元数据中心”。
 *
 * <p>This is the only interface in Spring's bean factory packages that encapsulates
 * <i>registration</i> of bean definitions. The standard BeanFactory interfaces
 * only cover access to a <i>fully configured factory instance</i>.
 *
 * 这是 Spring BeanFactory 包中唯一一个封装了 BeanDefinition “注册”能力的接口。
 * 标准的 BeanFactory 接口只负责获取已经创建好的 Bean 实例，
 * 而 BeanDefinitionRegistry 则专注于“元数据”的注册与维护。
 * ——这体现了“职责分离”的设计思想（Separation of Concerns）。
 *
 * <p>Spring's bean definition readers expect to work on an implementation of this
 * interface. Known implementors within the Spring core are DefaultListableBeanFactory
 * and GenericApplicationContext.
 *
 * Spring 的各种 BeanDefinitionReader（如 XML/Properties Reader）都依赖此接口来注册解析到的 BeanDefinition。
 * 在 Spring 核心中，常见的实现类有 DefaultListableBeanFactory 和 GenericApplicationContext。
 * ——这表明 BeanDefinitionRegistry 处于“容器元数据装配链路”的关键位置。
 *
 * <h2>设计解读 / Design Analysis</h2>
 * 1. 核心功能：
 *    - 维护 BeanDefinition 注册表，支持动态注册、删除和查询。
 *    - 它只关注 BeanDefinition（元数据），不直接管理 Bean 实例。
 *
 * 2. 逻辑流程：
 *    - Reader（如 XmlBeanDefinitionReader）解析配置文件 -> 调用 registry.registerBeanDefinition()
 *    - BeanFactory 根据注册表中的 BeanDefinition -> 实例化 Bean 并进行依赖注入
 *    - 可以在运行时通过 registry 动态修改 BeanDefinition（例如 Spring Boot 自动配置）
 *
 * 3. 在 Spring 框架中的作用：
 *    - 上游调用者：各种 BeanDefinitionReader（XML、Properties、注解扫描器）
 *    - 下游依赖者：BeanFactory / ApplicationContext 通过它获取元数据来实例化 Bean
 *    - 它是“配置阶段（Configuration Phase）”和“实例化阶段（Instantiation Phase）”之间的桥梁
 *
 * 4. 用到的设计模式：
 *    - **Registry Pattern（注册表模式）**：集中管理 BeanDefinition 元数据
 *    - **Strategy Pattern（策略模式）**：不同的 Reader 可以以统一方式注册 BeanDefinition
 *    - **Separation of Concerns（关注点分离）**：元数据管理与实例管理解耦
 *    - 优点：扩展性强，支持多种配置方式（XML、注解、Java Config）
 *    - 缺点：增加了一个中间层，学习曲线更陡峭，调试时可能需要跨越多层调用链
 *
 * @author Juergen Hoeller
 * @since 26.11.2003
 * @see org.springframework.beans.factory.config.BeanDefinition
 * @see AbstractBeanDefinition
 * @see RootBeanDefinition
 * @see ChildBeanDefinition
 * @see DefaultListableBeanFactory
 * @see org.springframework.context.support.GenericApplicationContext
 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
 * @see PropertiesBeanDefinitionReader
 */
public interface BeanDefinitionRegistry extends AliasRegistry {

	/**
	 * Register a new bean definition with this registry.
	 * Must support RootBeanDefinition and ChildBeanDefinition.
	 * @param beanName the name of the bean instance to register
	 * @param beanDefinition definition of the bean instance to register
	 * @throws BeanDefinitionStoreException if the BeanDefinition is invalid
	 * @throws BeanDefinitionOverrideException if there is already a BeanDefinition
	 * for the specified bean name and we are not allowed to override it
	 * @see GenericBeanDefinition
	 * @see RootBeanDefinition
	 * @see ChildBeanDefinition
	 */
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException;

	/**
	 * Remove the BeanDefinition for the given name.
	 * @param beanName the name of the bean instance to register
	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
	 */
	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * Return the BeanDefinition for the given bean name.
	 * @param beanName name of the bean to find a definition for
	 * @return the BeanDefinition for the given name (never {@code null})
	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
	 */
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * Check if this registry contains a bean definition with the given name.
	 * @param beanName the name of the bean to look for
	 * @return if this registry contains a bean definition with the given name
	 */
	boolean containsBeanDefinition(String beanName);

	/**
	 * Return the names of all beans defined in this registry.
	 * @return the names of all beans defined in this registry,
	 * or an empty array if none defined
	 */
	String[] getBeanDefinitionNames();

	/**
	 * Return the number of beans defined in the registry.
	 * @return the number of beans defined in the registry
	 */
	int getBeanDefinitionCount();

	/**
	 * Determine whether the given bean name is already in use within this registry,
	 * i.e. whether there is a local bean or alias registered under this name.
	 * @param beanName the name to check
	 * @return whether the given bean name is already in use
	 */
	boolean isBeanNameInUse(String beanName);

}
